package ws.performancetest.app.gui;

import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import ws.utils.jdbc.DBConnection;
import ws.performancetest.app.gui.strings.AppStrings;

/**
 * This class listens to connections established with the database.
 *
 * <p>When one connection is created or closed, this thread is awaken,
 * and then performs, some action.
 * </p>
 * <p>In this example, this thread enables/disables GUI controls. This controls
 * are saved on a list. To add one component use {@code addComponent}.
 * </p>
 * <p>This threads knows the some connection was established, because connections
 * are created using the class {@link DBSettings}, and this class has a method
 * that notifies when changes are made, {@code waitForChanges}.
 *
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class DBConnectionListener extends Thread {

  private static final DBConnectionListener reference = new DBConnectionListener();
  private static final List<JComponent> componentList = new LinkedList<JComponent>();

  /** Prevent instantiation. */
  private DBConnectionListener() {
    start();
  }

  /**
   * Get reference.
   *
   * @return DBConnectionListener instance.
   */
  public static DBConnectionListener getReference() {
    return reference;
  }

  /**
   * Add one component to the list.
   *
   * @param component javax.swing.JComponent to be added.
   */
  public static synchronized void addComponent(JComponent component) throws SQLException {
    componentList.add(component);
    changeComponentsState();
  }

  /**
   * Change the state to enabled/disabled, accordingly with connection status.
   */
  private static synchronized void changeComponentsState() throws SQLException {
    boolean flag;
    String toolTip;
    if (DBConnection.isOnline()) {
      flag = true;
      toolTip = null;
    } else {
      flag = false;
      toolTip = AppStrings.msgOptionNotAvailableOffline;
    }
    for (JComponent component : componentList) {
      component.setEnabled(flag);
      component.setToolTipText(toolTip);
    }
  }

  /**
   * Wait for connection changes (connect/disconnect) and then enable/disable
   * GUI controls.
   */
  @Override
  public void run() {
    while (true) {
      try {
        DBConnection.waitForChanges();
        changeComponentsState();
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
  }
}
